<template>
  <transition
    v-on:before-enter="beforeEnter"
    v-on:enter="enter"
    v-on:after-enter="afterEnter"
    v-on:enter-cancelled="enterCancelled"
    v-on:before-leave="beforeLeave"
    v-on:leave="leave"
    v-on:after-leave="afterLeave"
    v-on:leave-cancelled="leaveCancelled"
  >
    <slot />
  </transition>
</template>

<script>
import unitOver from './over'
export default {
  name: 'transtionWidth',
  components: { unitOver },
  props: {},
  data() {
    return {}
  },
  computed: {},
  watch: {},
  methods: {
    addClass(el, classname) {
      el.className.indexOf(classname) > -1
        ? null
        : (el.className += (el.className ? ' ' : '') + classname)
    },
    removeClass(el, classname) {
      el.className.indexOf(classname) > -1
        ? (el.className = el.className
            .split(classname)
            .filter((v) => v != ' ' && v != '')
            .join(' '))
        : null
    },
    beforeEnter(el) {
      el.style.width = 0
      el.style.opacity = 0
      this.addClass(el, 'transtion-width-enter')
    },
    enter(el) {
      el.dataset.oldOverflow = el.style.overflow
      if (el.scrollWidth !== 0) {
        el.style.width = el.scrollWidth + 'px'
        el.style.opacity = 1
      } else {
        el.style.width = ''
        el.style.opacity = ''
      }
      el.style.overflow = 'hidden'
    },
    afterEnter(el) {
      // for safari: remove class then reset width is necessary
      this.removeClass(el, 'transtion-width-enter')
      el.style.width = ''
      el.style.opacity = ''
      el.style.marginRight = el.dataset.oldMarginRight
      el.style.overflow = el.dataset.oldOverflow
    },
    beforeLeave(el) {
      this.addClass(el, 'transtion-width-leave')
      if (!el.dataset) el.dataset = {}
      el.dataset.oldMarginRight = el.style.marginRight
      el.dataset.oldOverflow = el.style.overflow
      el.style.width = el.scrollWidth + 'px'
      el.style.opacity = 1
      el.style.overflow = 'hidden'
    },
    leave(el) {
      if (el.scrollWidth !== 0) {
        // for safari: add class after set height, or it will jump to zero height suddenly, weired
        el.style.width = 0
        el.style.opacity = 0
        el.style.marginRight = 0
      }
    },
    afterLeave(el) {
      this.removeClass(el, 'transtion-width-leave')
      el.style.width = ''
      el.style.opacity = ''
      el.style.marginRight = ''
      el.style.overflow = el.dataset.oldOverflow
    },
    enterCancelled(el) {},
    leaveCancelled(el) {},
  },
}
</script>
<style scoped>
.transtion-width-enter {
  display: inline-block;
  overflow: hidden;
  white-space: nowrap;
  -webkit-transition: all 0.25s ease, opacity 0.4s ease, margin 0.1s ease 0.1s;
  -moz-transition: all 0.25s ease, opacity 0.4s ease, margin 0.1s ease 0.1s;
  -o-transition: all 0.25s ease, opacity 0.4s ease, margin 0.1s ease 0.1s;
  transition: all 0.25s ease, opacity 0.4s ease, margin 0.1s ease 0.1s;
}
.transtion-width-leave {
  display: inline-block;
  overflow: hidden;
  white-space: nowrap;
  -webkit-transition: all 0.25s ease, opacity 0.2s ease, margin 0.1s ease 0.1s;
  -moz-transition: all 0.25s ease, opacity 0.2s ease, margin 0.1s ease 0.1s;
  -o-transition: all 0.25s ease, opacity 0.2s ease, margin 0.1s ease 0.1s;
  transition: all 0.25s ease, opacity 0.2s ease, margin 0.1s ease 0.1s;
}
</style>
